package com.ruoyi.web.controller.utils;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Json和Object互相转换
 *
 */
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();
    // 定义jackson对象，忽略解析JSON字符串中Java对象中没有的字段设置
    private static final ObjectMapper MAPPER_IGNORE_UNKNOWN_PROPERTIES = new ObjectMapper();

    static {
        MAPPER_IGNORE_UNKNOWN_PROPERTIES.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
    	try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER_IGNORE_UNKNOWN_PROPERTIES.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json结果集转化为对象，忽略解析JSON字符串中Java对象中没有的字段设置
     *
     * @param jsonData json数据
     * @return
     */
    public static <T> T jsonToPojoIgnoreUnknownProperties(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER_IGNORE_UNKNOWN_PROPERTIES.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
    	JavaType javaType = MAPPER_IGNORE_UNKNOWN_PROPERTIES.getTypeFactory().constructParametricType(List.class, beanType);
    	try {
    		List<T> list = MAPPER_IGNORE_UNKNOWN_PROPERTIES.readValue(jsonData, javaType);
    		return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
    	
    	return null;
    }

    public static <T>List<T> jsonToListIgnoreUnknownProperties(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER_IGNORE_UNKNOWN_PROPERTIES.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER_IGNORE_UNKNOWN_PROPERTIES.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    public static  String xml2JSON(String xml) {
        JSONObject obj = new JSONObject();
         try {
             Document doc = DocumentHelper.parseText(xml);
             Element root = doc.getRootElement();
             obj.put(root.getName(), iterateElement(root));
             return obj.toString();
         } catch (Exception e) {
                e.printStackTrace();
                 return null;
         }
    }


    /**
     37      * 一个迭代方法
     38      *
     39      * @param element
     40      * @return java.util.Map 实例
     41      */
      @SuppressWarnings("unchecked")
      private static Map iterateElement(Element element) {
          List jiedian = element.elements();
          Element et = null;
          Map obj = new HashMap();
          Object temp;
          List list = null;
          for (int i = 0; i < jiedian.size(); i++) {
                list = new LinkedList();
                 et = (Element) jiedian.get(i);
                 if (et.getTextTrim().equals("")) {
                         if (et.elements().size() == 0)
                                 continue;
                         if (obj.containsKey(et.getName())) {
                                 temp = obj.get(et.getName());
                                 if(temp instanceof List){
                                         list = (List)temp;
                                         list.add(iterateElement(et));
                                     }else if(temp instanceof Map){
                                         list.add((HashMap)temp);
                                         list.add(iterateElement(et));
                                     }else{
                                         list.add((String)temp);
                                         list.add(iterateElement(et));
                                     }
                                 obj.put(et.getName(), list);
                             }else{
                                 obj.put(et.getName(), iterateElement(et));
                             }
                     } else {
                         if (obj.containsKey(et.getName())) {
                                 temp = obj.get(et.getName());
                                 if(temp instanceof List){
                                         list = (List)temp;
                                         list.add(et.getTextTrim());
                                     }else if(temp instanceof Map){
                                         list.add((HashMap)temp);
                                         list.add(iterateElement(et));
                                     }else{
                                         list.add((String)temp);
                                         list.add(et.getTextTrim());
                                     }
                                 obj.put(et.getName(), list);
                             }else{
                                 obj.put(et.getName(), et.getTextTrim());
                             }

                     }

             }
         return obj;
     }
}
